/**
 * Copyright (c) 2006
 *      OpenAVS Developers. All Rights Reserved.
 *
 * Copyright (c) 2005-2006
 *      NSCC. All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

/**
 * ! \file "global.c"
 *   \brief Global variables and functions.
 */

#include "endian.h"
#include "define.h"
#include "global.h"
#include "stream.h"
#include "vlc.h"

/* global variables ------------------------------- */
AVS_BYTE ClipTable[CLIPSIZE * 2 + 256];
AVS_INT  TabNoBuf[1025];
AVS_INT  TabNoBuf2[1025];

//dingo add
//Get Block Temp Var
int Blockcount[3][3];
int GBT[13][13];			//all Temp Pix
int GBT5[13][13];			//pix = pix * 5
int GBT8[13][13];			//pix = pix * 8
STREAMINFO strmInfo;
FILE *p_OUT;


const AVS_INT ShiftTable[64] = {
	15, 15, 15, 15, 15, 15, 15, 15,
	14, 14, 14, 14, 14, 14, 14, 14,
	14, 13, 13, 13, 13, 13, 13, 13,
	12, 12, 12, 12, 12, 12, 12, 12,
	12, 11, 11, 11, 11, 11, 11, 11,
	11, 10, 10, 10, 10, 10, 10, 10,
	10,  9,  9,  9,  9,  9,  9,  9,
	 8,  8,  8,  8,  8,  8,  8,  8

};

const AVS_FLOAT fPictureRates[] = {
	 0.0,
	23.976,
	24.0,
	25.0,
	29.97,
	30.0,
	50.0,
	59.94,
	60.0
};

const AVS_BYTE NCBP[64][2]= {
	{63,  0}, {15, 15}, {31, 63}, {47, 31}, 
	{ 0, 16}, {14, 32}, {13, 47}, {11, 13},
	{ 7, 14}, { 5, 11}, {10, 12}, { 8,  5},
	{12, 10}, {61,  7}, { 4, 48}, {55,  3},
	{ 1,  2}, { 2,  8}, {59,  4}, { 3,  1},
	{62, 61}, { 9, 55}, { 6, 59}, {29, 62},
	{45, 29}, {51, 27}, {23, 23}, {39, 19},
	{27, 30}, {46, 28}, {53,  9}, {30,  6}, 
	{43, 60}, {37, 21}, {60, 44}, {16, 26},
	{21, 51}, {28, 35}, {19, 18}, {35, 20},
	{42, 24}, {26, 53}, {44, 17}, {32, 37},
	{58, 39}, {24, 45}, {20, 58}, {17, 43},
	{18, 42}, {48, 46}, {22, 36}, {33, 33}, 
	{25, 34}, {49, 40}, {40, 52}, {36, 49},
	{34, 50}, {50, 56}, {52, 25}, {54, 22},
	{41, 54}, {56, 57}, {38, 41}, {57, 38}
};

const AVS_BYTE NCBP422[4][2]= {
	{0, 0},  {1, 1},  {2, 2},  {3, 3}
};


const AVS_DWORD MvNum[53] = {
	/* Intra Mode */
	0,
	/* P Mb Mode */
	0, 1, 2, 2, 4,
	/* B Mb Mode */
	0, 0, 1, 1, 1,
	2, 2, 2, 2, 2,
	2, 2, 2, 2, 2,
	2, 2, 2, 2, 2,
	2, 2, 2, 0, 0,
	1, 1, 1
};

const AVS_INT DequantTable[64] = {
	32768, 36061, 38968, 42495, 46341, 50535, 55437, 60424,
	32932, 35734, 38968, 42495, 46177, 50535, 55109, 59933,
	65535, 35734, 38968, 42577, 46341, 50617, 55027, 60097,
	32809, 35734, 38968, 42454, 46382, 50576, 55109, 60056,
	65535, 35734, 38968, 42495, 46320, 50515, 55109, 60076,
	65535, 35744, 38968, 42495, 46341, 50535, 55099, 60087,
	65535, 35734, 38973, 42500, 46341, 50535, 55109, 60097,
	32771, 35734, 38965, 42497, 46341, 50535, 55109, 60099
};

/**
 * Function: Construct Clip table to replace Clip macro.
 */
void MakeClipTable()
{
	AVS_BYTE * p = ClipTable;
	AVS_INT i;
	memset(p, 0, CLIPSIZE);
	p = ClipTable + CLIPSIZE;
	for (i = 0; i < 256; i++)
		*(p++) = i;
	memset(p, 255, CLIPSIZE);
}

/**
 * Function: Construct TabNo table.
 * used to look up table instead of making decisions and evaluating ABS in
 * VLD process.
 */
void MakeTabNoBuf()
{
	int i;
	TabNoBuf[512] = 0;
	for (i = 1; i <= 2; i++) {
		TabNoBuf[512 + i] = TabNoBuf[512 - i] = i;
	}
	for (i = 3; i <= 4; i++) {
		TabNoBuf[512 + i] = TabNoBuf[512 - i] = 3;
	}
	for (i = 5; i <= 7; i++) {
		TabNoBuf[512 + i] = TabNoBuf[512 - i] = 4;
	}
	for (i = 8; i <= 10; i++) {
		TabNoBuf[512 + i] = TabNoBuf[512 - i] = 5;
	}
	for (i = 11; i <= 512; i++) {
		TabNoBuf[512 + i] = TabNoBuf[512 - i] = 6;
	}

	// table2
	TabNoBuf2[512] = 0;
	for (i = 1; i <= 3; i++) {
		TabNoBuf2[512 + i] = TabNoBuf2[512 - i] = i;
	}
	for (i = 4; i <= 6; i++) {
		TabNoBuf2[512 + i] = TabNoBuf2[512 - i] = 4;
	}
	for(i = 7; i <= 9; i++) {
		TabNoBuf2[512 + i] = TabNoBuf2[512 - i] = 5;
	}
	for(i = 10; i < 512; i++) {
		TabNoBuf2[512 + i] = TabNoBuf2[512 - i] = 6;
	}
}


/**
 * Function: seek for next Start/End code.
 * To make sure current data is a whole frame of data.
 */
AVS_BOOL FindNextPicOrEndStartCode(
		const AVS_BYTE * pbData, AVS_DWORD dwDataLen, 
		AVS_DWORD* dwLeft)
{
	const AVS_BYTE * pbCurrent = pbData + 4;
	AVS_DWORD Left = dwDataLen - 4;

	while ((Left > 4) && 
#if __BYTE_ORDER == __LITTLE_ENDIAN
	       ((*(AVS_DWORD *) pbCurrent) != 0xB3010000) && 
	       ((*(AVS_DWORD *) pbCurrent) != 0xB6010000) &&
	       ((*(AVS_DWORD *) pbCurrent) != 0xB1010000)
#elif __BYTE_ORDER == __BIG_ENDIAN
		((*(AVS_DWORD *) pbCurrent) != 0x000001B3) &&
		((*(AVS_DWORD *) pbCurrent) != 0x000001B6) &&
		((*(AVS_DWORD *) pbCurrent) != 0x000001B1)
#else
#error "Cannot determine byte order"
#endif
	) {
		pbCurrent ++;
		Left --;
	}

	if (Left > 4) {
		*dwLeft = Left;
		return TRUE;
	}
	return FALSE;
}

/**
 * Function: seek for next slice header.
 */
AVS_BOOL FindSliceStartCode(const AVS_BYTE** pbData, AVS_DWORD* dwLeft)
{
	const AVS_BYTE * pbCurrent = *pbData;
	AVS_DWORD Left = *dwLeft;

	while (Left > 4 && 
	       ! IS_SLICE_START_CODE(DWORD_SWAP(*(AVS_DWORD *) pbCurrent))) {
		pbCurrent ++;
		Left --;
	}

	if (Left > 4) {
		*pbData = pbCurrent;
		*dwLeft = Left;
		return TRUE;
	}
	return FALSE;
}

/**
 * Function: Decide if input is slice header or not.
 */
AVS_BOOL IsSliceHeader(const AVS_BYTE * pbData, AVS_DWORD dwBitOffset)
{

	AVS_DWORD dwByteOffset = dwBitOffset / 8;
	if (dwBitOffset % 8 > 0)
		dwByteOffset += 1;
	return IS_SLICE_START_CODE(DWORD_SWAP(*(AVS_DWORD*)(pbData+dwByteOffset)));

}

/**
 * Function: Allocate memory for reference picture.
 */
AVS_HRESULT GetMem(VIDEODATA ** refFrame, AVS_INT refNum)
{
	AVS_INT iYlen = AVS_MAX_HORIZONTAL*AVS_MAX_VERTICAL;
	AVS_INT iUVlen = iYlen/4;

	AVS_INT i;

	for (i = 0; i < refNum; i++) {
		refFrame[i] = malloc(sizeof(VIDEODATA));
	}

	for (i = 0; i < refNum; i++) {
		refFrame[i]->y = malloc(sizeof(AVS_BYTE) * iYlen);
		refFrame[i]->u = malloc(sizeof(AVS_BYTE) * iUVlen);
		refFrame[i]->v = malloc(sizeof(AVS_BYTE) * iUVlen);
	}

	return AVS_NOERROR;
}

/**
 * Function: Release memory for reference picture.
 */
void ReleaseMem(VIDEODATA* refFrame[], AVS_INT refNum)
{
	AVS_INT i;

	for (i = 0; i < refNum; i++) {
		free(refFrame[i]->y);
		free(refFrame[i]->u);
		free(refFrame[i]->v);
		free(refFrame[i]);
	}
}

